/* eslint-disable */

import { getStorageValue, setStorageValue, removeStorageValue } from '/src/utils'
import { funcSortColumns } from '/src/utils'
import { ref, unref, reactive, h, watch } from 'vue'
import { post } from "/src/api/index";
import { ElMessage } from '/src/utils'
import { batchUpdateValue } from '/src/utils'
import { ElMessageBox } from 'element-plus'
import { ArrowLeft, ArrowRight } from '@element-plus/icons-vue'

import dayjs from 'dayjs'

export function fixBlankFileds(obj, obj_ori, columns) {
  let objOri = {...(obj_ori || {})}
  for (let p in objOri) {
    if (typeof(objOri[p]) === 'string') {
      objOri[p] = objOri[p].trim()
    }
  }

  let objOut = {...obj}
  let count = 0
  for (let p in objOut) {
    if (p == 'updated_at'
      || p == 'updatedby'
      || p == '#'
    ) {
      delete objOut[p]
      continue;
    }
    let column = null
    if (columns) {
      column = columns.find(item => item.prop === p)
    }
    if (column && column.discard) {
      delete objOut[p]
      continue;
    }
    if (typeof(objOut[p]) === 'string') {
      objOut[p] = objOut[p].trim()
    }
    if (column && column.force_update) {

    } else {
      if (objOut[p] instanceof Array && objOut[p].length == 0) {
        if (!(p in objOri)) {
          delete objOut[p]
          continue;
        }
        if (objOri[p] instanceof Array && objOri[p].length == 0) {
          delete objOut[p]
          continue;
        }
      }
      if (objOut[p] === '' || objOut[p] === null || objOut[p] === undefined) {
        if (!(p in objOri)) {
          delete objOut[p]
          continue;
        }
        if (objOri[p] === '' || objOri[p] === null || objOri[p] === undefined) {
          delete objOut[p]
          continue
        }
      }
      if (p in objOri && objOut[p] === objOri[p]) {
        delete objOut[p]
        continue;
      }
      if (column && objOut[p] === null && (column.type == 'datetime' || column.type == 'date' || column.type == 'year')) {
        if (!('query_options_setnull' in objOut)) {
          objOut.query_options_setnull = {}
        }
        objOut.query_options_setnull[p] = 1
        delete objOut[p]
      } else  if (column && objOut[p] === '') {
        if (column.type == 'number' || column.type == 'select') {
          if (!('query_options_setnull' in objOut)) {
            objOut.query_options_setnull = {}
          }
          objOut.query_options_setnull[p] = 1
          delete objOut[p]
        }
      }
    }
    count++
  }
  if (count == 0) {
    return null;
  }

  return objOut
}

export function init(self) {
  self.fixBlankFileds = fixBlankFileds
  self.buttons = ref([])
  self.insertLineColunmn = () => {
    // self.columns.value.splice(0, 0, {
    //   prop: '#',
    //   label: '#',
    //   type: 'index',
    //   fixed: true,
    //   width: 60,
    //   sortable: false,
    //   discard_export: true,
    // })
  }
  self.insertLineColunmn();

  //不导出id
  {
    const column = unref(self.columns).find(e => e.prop == 'id')
    if (column) {
      column.discard_export = true
    }
  }

  //设置列表的remark字段宽度
  {
    const column = unref(self.columns).find(e => e.prop == 'remark')
    if (column) {
      column.width = 300
    }
  }

  //设置编辑form的remark字段类型
  {
    const column = unref(self.editColumns).find(e => e.prop == 'remark')
    if (column) {
      column.type = 'textarea'
    }
  }

  const customButtons = (self.custom || {}).buttons || []
  const customColumns = (self.custom || {}).columns || []
  const customEditColumns = (self.custom || {}).editColumns || []
  const customqueryColumns = (self.custom || {}).queryColumns || []
  const customRemoteConfig = (self.custom || {}).remoteConfig || {}

  // console.log('module', self.module.value)

  self.columns.value = funcSortColumns(self.columns.value, customColumns, 'columns')
  self.editColumns.value = funcSortColumns(self.editColumns.value, customEditColumns, 'editColumns')
  self.queryColumns.value = funcSortColumns(self.queryColumns.value, customqueryColumns, 'queryColumns')

  self.editColumns.value.forEach( column => {
    if (column.type == 'double' && !column.onchange) {
      column.onchange =  (param) => {
        let {mode, form, column, columns, get_remote_list, set_query_storage} = param
        if (form[column.prop] !== null && form[column.prop] !== undefined) {
          try {
            let v = parseFloat(form[column.prop])
            if (isNaN(v)) {
              form[column.prop] = ''
            } else {
              if (v+'' != form[column.prop]) {
                form[column.prop] = v+''
              }
            }
          }catch(ex) {
            form[column.prop] = ''
          }
        }
      }
    }
  })

  for(let p in customRemoteConfig) {
    let item = customRemoteConfig[p]
    let oriItem = self.remoteConfig.value[p]
    if (oriItem) {
      for(let p in item) {
        oriItem[p] = item[p]
      }
    } else {
      self.remoteConfig.value[p] = item
    }
  }

  customButtons.forEach ( item => {
    let oriItem = self.buttons.value.find( ele => ele.prop == item.prop)
    if (oriItem) {
      for(let p in item) {
        oriItem[p] = item[p]
      }
    } else {
      self.buttons.value.push(item)
    }
  })

  let queryInfoList = self.queryColumns.value

  let pageSize = getStorageValue('pageSize')
  if (!pageSize) {
    pageSize = 10
  } else {
    pageSize = parseInt(pageSize)
  }
  queryInfoList = [
    ...queryInfoList,
    {prop: 'pageNo', default: 1, result_value_type: 'int'},
    {prop: 'pageSize', default: pageSize, result_value_type: 'int'}
  ]
  let workspaceName = getStorageValue('workspace_name')

  self.loadSort = () => {
    let sortInfo = getStorageValue('order_'+self.name.value)
    if (!sortInfo || !(sortInfo instanceof Array) || !sortInfo.length) {
      if(self.custom){
        let orderIndex = 0
        sortInfo = unref(unref(self.custom).columns).filter(ele => ele.order_ori).map(ele => {
          return {
            prop: ele.prop,
            order: ele.order_ori,
            orderIndex: ++orderIndex,
          }
        })
      }
      
    }
    if (sortInfo && sortInfo instanceof Array && sortInfo.length > 0) {
      unref(self.columns).forEach(item => {
        delete item.order
        delete item.orderIndex
      })
  
      let sortInfoMap = {}
      sortInfo.forEach((item) => {
        if (item.order) {
          sortInfoMap[item.prop] = item
        }
      })
      unref(self.columns).forEach(item => {
        if (item.prop in sortInfoMap) {
          item.order = sortInfoMap[item.prop].order
          item.orderIndex = sortInfoMap[item.prop].orderIndex
        }
      })
    }
  }
  unref(self.columns).forEach( ele => {
    if (ele.order) {
      ele.order_ori = ele.order
    }
  })
  self.loadSort();

  self.query = ref({})

  for(let i in queryInfoList) {
    i = queryInfoList[i]
    if (i.hide === true) {
      continue;
    }
    if (i.prop === 'workspace_name' && workspaceName) {
      i.default = workspaceName
      self.query.value[i.prop] = i.default
      continue;
    }
    
    let v = getStorageValue('query_'+self.name.value+'_'+i.prop)
    try {
      const newV = JSON.parse(v)
      if (newV instanceof Array) {
        v = newV
      }
    }catch(ex) {

    }
    if (v || v === 0) {
      self.query.value[i.prop] = v;
    }
  }

  self.init_remote_list = (columns, param)  => {
    let { query } = param
    columns.forEach( column => {
      let r = column.list_remote
      if (r && r.mode !== 'dynamic') {
        column.list = []
        let r_query = {...(r.query || {})}
        post(r.module, r.method, r_query, {sortInfo:r.sortInfo})
        .then( data => {
          if(r.cbBefore) {
            r.cbBefore({...self, mode: 'remote init before', column, columns, data})
          }
          data.forEach( item => {
              column.list.push({ label:item[r.mapInfo.label], value:item[r.mapInfo.value], data: item})
            })
          let cb = r.cb
          if (typeof(cb) == 'string') {
            cb = ((columns.find( item2 => item2.prop == cb) || {}).list_remote || {}).cb
          }
          if(cb) {
            cb({...self, mode: 'remote init', column, columns, data})
          }
        })
      }      
    })
  }

  self.init_remote_list(self.queryColumns.value, {query: unref(self.query)})

  self.selectRows = ref([])

  self.multipleTable = ref(null)

  self.tablePagination = ref(null)

  self.sortColumns = ref([])

  self.tableData = ref([]);
  self.pageTotal = ref(0);

  self.discardCount = ref(false)

  self.loadingSearch = ref(false)

  self.loadingDelete = ref(false)

  self.loadingExport = ref(false)

  self.pageSizes = ref([10,50,100,1000])

  self.editDialog = ref(null)
  self.editForm = ref(null)

  self.form_rules = ref([])

  self.editTitle = ref('')
  self.editVisible = ref(false)
  self.form = ref({})
  self.form_ori = ref({})

  self.onTableSelectionChange = (a, b, c) => {
    self.selectRows.value = a
  }

  self.get_remote_list = params => {
    let {columns, prop, query, form} = params
    try {
      let column = columns.find( item => item.prop == prop);
      if (!column || !column.list_remote) {
        let msg = '未找到属性:'+prop
        ElMessage.error(msg);
        return Promise.reject(new Error(msg));
      }
      const r = column.list_remote
  
      query = {...r.query, ...query}
      return post(r.module, r.method, query, {sortInfo:r.sortInfo})
      .then( data => {
        column.list = []
        if(r.cbBefore) {
          r.cbBefore({...self, mode: 'remote init before', column, columns, data})
        }
        data.forEach( item => {
          column.list.push({ label:item[r.mapInfo.label], value:item[r.mapInfo.value], data: item})
        })
        let cb = r.cb
        if (typeof(cb) == 'string') {
          cb = ((columns.find( item2 => item2.prop == cb) || {}).list_remote || {}).cb
        }
        if(cb) {
          cb({...self, ...params, column, columns, data})
        }
        return {...self, ...params, column, data}
      })
    }catch(ex) {
      console.error('get_remote_list fail', ex)
      ElMessage.error('无法获取信息'+ex);
      return Promise.reject(new Error(ex));
    }
  }

  const set_query_storage = (form, prop, value) => {
    form[prop] = value
    setStorageValue('query_'+self.name.value+'_'+prop, value)
  }

  self.set_query_storage = set_query_storage

  const onChange = (param) => {
    const {mode, form, column, columns} = param
    // console.log('onChange', mode, form, column, param)
    if (mode == 'query') {
      self.discardCount.value = false
    }
    if (form[column.prop] instanceof Array) {
      let newForm = []
      let foundBlank = false
      form[column.prop].forEach( item => {
        if (item === '') {
          foundBlank = true
        } else {
          newForm.push(item)
        }
      })
      if (foundBlank && newForm.length > 0) {
        form[column.prop] = newForm
      }
    }
    if (mode == 'query') {
      if (column.prop == 'workspace_name') {
        setStorageValue('workspace_name', form[column.prop])
      } else {
        setStorageValue('query_'+self.name.value+'_'+column.prop, form[column.prop])
      }
    }

    if (mode !== 'dialog' && column.oninit) {
      let cb = column.oninit
      if (typeof(cb) == 'string') {
        cb = (columns.find( item2 => item2.prop == column.oninit) || {}).oninit
      }
      if(cb) {
        cb({...self, ...param})
      }
    } else if (column.onchange) {
      let cb = column.onchange
      if (typeof(cb) == 'string') {
        cb = (columns.find( item2 => item2.prop == column.onchange) || {}).onchange
      }
      if(cb) {
        cb({...self, ...param})
      }
    }
  }

  const onFocus = (param) => {
    const {mode, form, column, columns} = param

    if (column.onfocus) {
      let cb = column.onfocus
      if (typeof(cb) == 'string') {
        cb = (columns.find( item2 => item2.prop == column.onfocus) || {}).onfocus
      }
      if(cb) {
        cb({...self, ...param})
      }
    }
  }

  self.sortMethod = a => {
    if (a) {
      let column = self.columns.value.find((item) => item.prop === a.property)
      if (column.order === 'desc' || column.order === 'desc/gbk') {
        column.order = null
        column.orderIndex = null
      } else if (column.sort_by_gbk) {
        if (column.order === 'asc/gbk' || column.order === 'asc') {
          // column.order = 'desc/gbk'
          column.order = 'desc'
        } else {
          // column.order = 'asc/gbk'
          column.order = 'asc'
        }
      } else {
        if (column.order === 'asc') {
          column.order = 'desc'
        } else {
          column.order = 'asc'
        }
      }
      if (column.order) {
        if (!column.orderIndex) {
          column.orderIndex = 0
          unref(self.columns).forEach((item) => {
            if (item.order && item.orderIndex > column.orderIndex) {
              column.orderIndex = item.orderIndex
            }
          })
          column.orderIndex++
        }
      } else {
        column.column_index = null
      }
      let orderList = []
      unref(self.columns).forEach ( item => {
        if (item.order && item.orderIndex >= 0) {
          orderList.push({prop: item.prop, order: item.order, orderIndex: item.orderIndex})
        }
      })
      setStorageValue(
        'order_' + self.name.value,
        orderList
      )
    }

    self.sortColumns.value = []
    unref(self.columns).forEach((item) => {
      if (item.order) {
        self.sortColumns.value.push(item)
      }
    })
    let sortCondition = []
    unref(self.sortColumns)
    .sort(function compareFunction(param1, param2) {
        return param1.orderIndex - param2.orderIndex
      })
      .forEach((item) => {
        item.orderIndex = sortCondition.length + 1
        let sortItem = new Object()
        sortItem[item.prop] = item.order
        sortCondition.push(sortItem)
      })

  }

  self.onRowClick = (a) => {
    if (unref(self.selectRows).length > 1) {
      let found = false
      unref(self.selectRows).forEach((item) => {
        if (item.id === a.id) {
          found = true
        }
      })
      if (found) {
        return
      }
      ElMessageBox.confirm('是否要取消其他选择状态？', '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        closeOnClickModal: false,
        type: 'warning',
      })
        .then(() => {
          if (unref(self.multipleTable).clearSelection) {
            unref(self.multipleTable).clearSelection()
          }
          if (unref(self.multipleTable).toggleRowSelection) {
            unref(self.multipleTable).toggleRowSelection(a)
          }
        })
        .catch(err => {
          if (unref(self.multipleTable).toggleRowSelection) {
            unref(self.multipleTable).toggleRowSelection(a)
          }
        })
    } else {
      if (unref(self.multipleTable).clearSelection) {
        unref(self.multipleTable).clearSelection()
      }
      if (unref(self.multipleTable).toggleRowSelection) {
        unref(self.multipleTable).toggleRowSelection(a)
      }
    }
  }

  self.processData = (data) => {
    try {
      // if (self.custom.processDataPre) {
      //   self.custom.processDataPre(data)
      // }
      const donePropSet = {}
      if (data && data.length && self.columns.value && self.columns.value.length) {
        let index = 1
        const columnnMap = {}
        data.forEach( item => {
          // item['#'] = index++
  
          for(const p in item) {
            let column = donePropSet[p]
            if (!column) {
              column = self.columns.value.find( column1 => column1.prop == p)
              if (!column) {
                column = {
                  prop: p,
                  label: p,
                }
                donePropSet[p] = column
                self.columns.value.push(column)
              }
            }
            if (column.oninit) {
              let cb = column.oninit
              if (typeof(cb) == 'string') {
                cb = (self.columns.value.find( item2 => item2.prop == cb) || {}).oninit
              }
              if (cb) {
                cb({...self, mode: 'init_data', form: item, column, columns: self.columns.value})
              }
            }
          }
        })

        // if (self.custom.processData) {
        //   self.custom.processData(data, self)
        // }
      }
    } catch(ex) {
      console.error('processData ex', ex)
    }
  }
  
  self.forceRefreshAfterUpdate = ref(false)

  self.cellClick = (row, column, cell, event) => {
    self.last_click_cell = {row, column, cell, property: column.property}
  }

  self.getData = (param) => {
    let { pageNo, pageSize, queryExtraParam, withoutSetData, withoutProcessParam } = param || {}
    self.forceRefreshAfterUpdate.value = false;
    let remoteCount = self.remoteConfig.value.count
    if (!remoteCount) {
      let msg = '未定义count'
      ElMessage.error(msg)
      return Promise.reject(msg);
    }
    let remoteList = self.remoteConfig.value.list
    if (!remoteList) {
      let msg = '未定义list'
      ElMessage.error(msg)
      return Promise.reject(msg);
    }
    if (self.loadingSearch.value) {
      ElMessage.error('正在查询，请稍后再试')
      return Promise.resolve();
    }
    self.loadingSearch.value = true;
    let query = fixBlankFileds(self.query.value)
    if (!query) {
      query = {}
    }
    if (withoutProcessParam) {
      if (query.query_options) {
        delete query.query_options.like
      }
    } else {
      let hasLike = false
      if (!query.query_options) {
        query.query_options = {}
      }
      let like = {}
      Object.keys(query).forEach( ele => {
        if (ele.indexOf('_like') >= 0) {
          if (query[ele]) {
            like[ele.replace('_like', '')] = '%' + query[ele] + '%'
            hasLike = true
            delete query[ele]
          }
        }
      })
      if (hasLike) {
        query.query_options['like'] = like
      } else {
        delete query.query_options.like
      }
      if (self.columns.value.find(ele => ele.prop == 'workspace_name')) {
        if (self.query.value.workspace_name) {
          setStorageValue('workspace_name', self.query.value.workspace_name)
        } else {
          setStorageValue('workspace_name', null)
        }
      }
    }

    if (self.sortColumns.value.length) {
      if (!('query_options' in query)) {
        query.query_options = {}
      }
      query.query_options.order_by = []
      self.sortColumns.value.forEach( item => {
        let newItem = {}
        newItem[item.prop] = item.order
        query.query_options.order_by.push(newItem)
      })
    }
    if (pageNo) {
      query.pageNo = pageNo
    }
    if (pageSize) {
      query.pageSize = pageSize
    }
    if (queryExtraParam) {
      query = {...query, ...queryExtraParam}
    }
    if (!query.pageSize) {
      let pageSize = getStorageValue('pageSize')
      if (!pageSize) {
        pageSize = 10
      } else {
        pageSize = parseInt(pageSize)
      }
      query.pageSize = pageSize
      self.query.value.pageSize = pageSize
    }

    
    let now = new Date()

    let count = null
    return post(remoteList.module, remoteList.method, query, {withConfig: true})
    .then(response => {
      let { data, config } = response
      if (data.code && data.msg) {
        throw new Error(data.msg)
      }
      if (data.body) {
        data = data.body
      } else {
        throw new Error('返回结果错误:'+JSON.stringify(data))
      }
      if (response.headers['count']) {
        count = parseInt(response.headers['count'])
        self.pageTotal.value = count
      }
      if ((new Date()).getTime() - now.getTime() > 30*1000) {
        console.log('after getData,', (new Date()).getTime() - now.getTime(), new Date())
      }
      self.processData(data)
      if (withoutSetData) {
        return data;
      }
      self.tableData.value = data
      return data
    })
    .then( data => {
      count = null
      self.discardCount.value = false
      if (count === null) {
        if (!((param||{}).forceCount) && self.discardCount.value) {
          self.loadingSearch.value = false;
        } else {
          return post(remoteCount.module, remoteCount.method, query)
          .then ( data2 => {
            self.loadingSearch.value = false;
            self.discardCount.value = true
            if ((new Date()).getTime() - now.getTime() > 30*1000) {
              console.log('after countData,', (new Date()).getTime() - now.getTime(), new Date())
            }
            now = new Date();
            self.pageTotal.value = data2
            return data
          })
        }
      } else {
        self.loadingSearch.value = false;
        self.discardCount.value = true
      }
      return data
    })
    .catch(err => {
      self.loadingSearch.value = false;
      console.error('err', err)
      ElMessage.error(`无法获取数据：${err}`)
      return Promise.reject(`无法获取数据:${err}`);
    })
  };

  self.resetSort = (param) => {
    ElMessageBox.confirm("确定要清空所有查询条件并重置排序字段吗？", "提示", {
      type: "warning",
    }).then(() => {
        let items = []
        for(let i = 0; i < localStorage.length; i++) {
          let key = localStorage.key(i)
          if (key.indexOf('query_'+unref(self.name) + '_') == 0) {
            items.push(key)
          }
        }
        items.push('order_'+unref(self.name))
        items.forEach( ele => {
          removeStorageValue(ele)
        })

        Object.keys(unref(self.query)).forEach(ele => {
          delete unref(self.query)[ele]
        })

        removeStorageValue('workspace_name')

        self.loadSort()
    })
  }

  self.lastCurrentRow = null
  self.handleCurrentChange = (param) => {
    if(param){
      self.lastCurrentRow = param
    }
  }

  self.handleSearch = (param) => {
    let selectRows = [...unref(self.selectRows)]
    let tableData = [...unref(self.tableData)]
    return self.getData(param)
    .then( data => {
      let firstRow
      let lastCurrentRow = self.lastCurrentRow
      unref(self.tableData).forEach( (ele, index) => {
        if(lastCurrentRow && lastCurrentRow.id == ele.id){
          firstRow = ele
        }
        let item = selectRows.find(e => e.id == ele.id)
        if (item) {
          if (unref(self.multipleTable).toggleRowSelection) {
            
            unref(self.multipleTable).toggleRowSelection(ele, true)
          }
        }
        item = tableData.find(e => e.id == ele.id)
        if (item && item.name_diff) {
          ele.name_diff = item.name_diff
        }
        if (firstRow) {
            unref(self.multipleTable).setCurrentRow(firstRow)
        }
      })
      return data
    })
  };

  self.handlePageChange = (val) => {
    self.query.value.pageNo = val;
    return self.handleSearch();
  };

  self.handleSizeChange = (val) => {
    self.query.value.pageSize = val;
    setStorageValue('pageSize', val)
  }

  self.handleExport = (a, b, c, d, e, form) => {

    let remote = self.remoteConfig.value.export_excel
    if (!remote) {
      ElMessage.error('未定义export_excel方法')
      return;
    }
    let discards = {}
    if (remote.discards) {
      remote.discards.forEach ( item => {
        discards[item] = 1
      })
    }

    let fields = []
    let export_excel_fields = []
    self.columns.value.forEach( item => {
      if (item.prop in discards) {
        return
      }
      if (item.hide) {
        return;
      }
      if (item.discard_export) {
        return;
      }
      fields.push(item.prop);
      export_excel_fields.push({prop:item.prop, title:item.label, width:(item.width || 200)/10})
    })

    self.loadingExport.value = true;
    let query = {
      ...fixBlankFileds(form || self.query.value),
      pageNo:undefined, pageSize:undefined,
      export_excel_fields,
    }

    if (!query) {
      query = {}
    }

    if (self.sortColumns.value.length) {
      if (!('query_options' in query)) {
        query.query_options = {}
      }
      query.query_options.order_by = []
      self.sortColumns.value.forEach( item => {
        let newItem = {}
        newItem[item.prop] = item.order
        query.query_options.order_by.push(newItem)
      })
    }

    if (self.custom.extra_export_query) {
      query = {...self.custom.extra_export_query, ...query}
    }
    if (self.custom.extra_export_columns && query.export_excel_fields) {
      for(const extraProp in self.custom.extra_export_columns) {
        const newArr = []
        for(const columnIndex in query.export_excel_fields) {
          const column = query.export_excel_fields[columnIndex]
          if (column.prop == extraProp) {
            for(let i = 0; i <= columnIndex; i++) {
              newArr.push(query.export_excel_fields[i])
            }
            for(let i = 0; i < self.custom.extra_export_columns[extraProp].length; i++) {
              newArr.push(self.custom.extra_export_columns[extraProp][i])
            }
            for(let i = columnIndex + 1; i < query.export_excel_fields.length; i++) {
              newArr.push(query.export_excel_fields[i])
            }
            break
          }
        }
        query.export_excel_fields = newArr
      }
    }

    post(remote.module, remote.method, query, {responseType: 'arraybuffer'})
    .then( data => {
      self.loadingExport.value = false;
      let link = document.createElement('a')
      let blob = new Blob([data], {
        type: 'application/vnd.ms-excel'
      })
      link.href = window.URL.createObjectURL(blob)
      link.download = self.module.value + '_' + dayjs().format('YYYYMMDDHHmmss') + '.xls'
      document.body.appendChild(link)
      link.click()
    })
    .catch(err => {
      ElMessage.error(`失败:${err}`, err);
      self.loadingExport.value = false;
    })
  }

  self.handleDelete = (index) => {
    if (self.selectRows.value.length == 0) {
      ElMessage.error('请先选择记录');
      return;
    }
      // 二次确认删除
      ElMessageBox.confirm("确定要删除吗？", "提示", {
          type: "warning",
      })
          .then(() => {
            let remote = self.remoteConfig.value.delete
            if (!remote.keys || remote.keys.length == 0) {
              ElMessage.error(`未配置keys:${remote}`);
              return;
            }
      
            self.loadingDelete.value = true;
            let form = {}
            remote.keys.forEach( key => {
              form[key] = []
              self.selectRows.value.forEach( row => {
                form[key].push(row[key])
              })
            })
            
            self.discardCount.value = false
            post(remote.module, remote.method, form)
            .then( data => {
              if (data) {
                ElMessage.success(`成功`);
                let selectRows = [...unref(self.selectRows)]
                let selectIndex = -1
                unref(self.tableData).forEach( (ele, index) => {
                  let item = selectRows.find(e => selectRows[0].id == ele.id)
                  if (item) {
                    selectIndex = index
                  }
                })
                self.loadingDelete.value = false;
                return self.handleSearch({forceCount:true})
                .then( data => {
                  if (selectIndex !== -1 && selectIndex < unref(self.tableData).length) {
                    if (unref(self.multipleTable).toggleRowSelection) {
                      unref(self.multipleTable).toggleRowSelection(unref(self.tableData)[selectIndex], true)
                    }
                  }
                })
              } else {
                ElMessage.error(`失败:${data}`);
                self.loadingDelete.value = false;
              }
            })
            .catch(err => {
              ElMessage.error(`失败:${err}`, err);
              self.loadingDelete.value = false;
            })
          })
          .catch(err => {
            ElMessage.error(`失败:${err}`, err);
            self.loadingDelete.value = false;
          });
  };

  self.getFormAndcheckRequired = ({form, columns}) => {
    let newForm = fixBlankFileds(form, null, columns)
    for(let item in columns) {
      item = columns[item]
      if (item.prop == 'updated_at'
        || item.prop == 'updatedby'
        || item.prop == '#'
      ) {
        continue;
      }
      if (item.required) {
        if (!newForm || !(item.prop in newForm) || !newForm[item.prop]) {
          ElMessage.error(`请输入:${item.label}`);
          return null;
        }
      }
    }
    return newForm
  }

  self.baseMounted = (v) => {
    for(let p in v) {
      self[p].value = v[p].value;
    }
  }

  self.cellDblclick = (row, propItem) => {
    if (row && propItem && row[propItem.property]) {
      let v = row[propItem.property] + ''
      if (v.length >= 20) {
        ElMessageBox({
          message: h('textarea', {rows: '20'}, row[propItem.property]),
          customClass:'cellDblclickClass',
        })
      }
    }
  }

  const getOnlySelectRowData = (selectRows) => {
    if (!selectRows || selectRows.length == 0) {
      ElMessage.error('请先选择记录');
      return null;
    }
    if (selectRows.length > 1) {
      ElMessage.error('只能选择一条记录进行编辑');
      return null;
    }
    return selectRows[0]
  }

  self.getOnlySelectRowData = getOnlySelectRowData

  self.handleSearchButton = ref({
    showMenu: false,

  })

  self.showQueryColumnsButton = ref({
    changed: 0,
    title: '',
    icon: '',
    showAll: false,
    onclick: param => {
      let button = unref(self.showQueryColumnsButton)
      button.showAll = button.showAll ? 0 : 1;
      button.icon = button.showAll ? ArrowLeft : ArrowRight
      setStorageValue('showAllQueryColumns', button.showAll)
      button.title = button.showAll? '隐藏空查询条件' : '显示所有查询条件'
      if (button.showAll) {
        button.changed = 0;
      }
    }
  })

  {
    let showAllQueryColumns = getStorageValue('showAllQueryColumns')
    let button = unref(self.showQueryColumnsButton)
    if (showAllQueryColumns === null || showAllQueryColumns === undefined) {
      button.showAll = 0;
    } else {
      button.showAll = showAllQueryColumns ? 0 : 1
    }
    button.onclick()
  }

  self.resetSortMenu = param => {
    console.log('resetSortMenu', param)
    let button = unref(self.handleSearchButton)
    button.showMenu = !button.showMenu
  }
  self.batchUpdateValueButton = ref({
    title:getStorageValue('batchUpdateValueButtonTitle') || '批量替换值(全部结果)',
    list: [
      {label:'批量替换值(全部结果)'},
      {label:'批量替换值(选中条目)'},
    ],
    loading:false,
    onclick: param => {
      let button = unref(self.batchUpdateValueButton)
      batchUpdateValue({param, self, selectOnly:button.title.indexOf('选中条目') >= 0})
    },
    oncommand: param => {
      let button = unref(self.batchUpdateValueButton)
      button.title = param
      setStorageValue('batchUpdateValueButtonTitle', button.title)
      button.onclick({...self, button})
    }
  })

  self.batchUpdateValueDialogInfo = ref({
    title: '批量替换值（全部结果）',
    visible:false,
    loading: false,
    rules:[],
    form:{},
    columns:[
      {
        prop: 'column_name',
        label: '字段',
        type: 'select',
        required: true,
        list: unref(self.columns).filter(ele => !(['id', 'workspace_name'].find(e => e == ele.prop))).map(ele => ({
          label: ele.prop + ' ' + ele.label,
          value: ele.prop,
        }))
      },
      {
        prop: 'value',
        label: '原值',
        required: true,
      },
      {
        prop: 'new_value',
        label: '新值',
      }
    ],
    onconfirm: (param) => {
      let {dialogInfo} = param
      if (!dialogInfo.form.column_name) {
        ElMessage.error('必须选择字段')
        return;
      }
      if (!dialogInfo.form.value) {
        ElMessage.error('必须输入原值')
        return;
      }
      let destValue = dialogInfo.form.new_value
      if (destValue === undefined || destValue === null) {
        destValue = ''
      }
      dialogInfo.loading = true
      self.handleSearch({
        pageNo: 1,
        pageSize: 10000,
        withoutSetData: true,
        // withoutProcessParam:  true,
      }).then(data => {
        if (dialogInfo.title.indexOf('选中条目') >= 0) {
          data = unref(self.selectRows)
        }
        let count = 0
        let module = unref(self.module)
        data.forEach(item => {
          let form = {id:item.id}
          let loop = 0
          let value = item[dialogInfo.form.column_name]
          if (value === undefined || value === null) {
            value = ''
          }
          while(loop < 100 && value.indexOf(dialogInfo.form.value) >= 0) {
            value = value.replace(dialogInfo.form.value, destValue)
          }
          form[dialogInfo.form.column_name] = value
          post(module, 'update', form)
          .then(() => {
            count++
            if (count == data.length) {
              dialogInfo.loading = false;
              dialogInfo.hide(param)
              self.handleSearch()
            }
          })
          .catch(ex => {
            console.error('ex', ex)
            dialogInfo.loading = false;
          })
        })
      })
    },
    hide: (param) => {
      const {dialogInfo} = param
      dialogInfo.form = {}
      dialogInfo.visible = false
      dialogInfo.loading = false
    },
    show: (param) => {
      let {dialogInfo, query, selectRows} = param

      dialogInfo.columns.forEach( item => {
        if (item.oninit) {
          item.oninit({...self, mode: 'init', dialogInfo:dialogInfo, column:item, columns: dialogInfo.columns, form: dialogInfo.form})
        }
      })

      dialogInfo.visible = true
    },
  })

  self.editDialogInfo = ref({
    title: ((self.editDialogInfo || ref({})).value || {}).title || '未知',
    visible:false,
    loading: false,
    rules:[],
    form:{},
    columns:[
      ...self.editColumns.value,
    ],
    edit2add: (param) => {
      const {dialogInfo, remoteConfig, getFormAndcheckRequired} = param
      dialogInfo.title = '添加';
      dialogInfo.form_ori = {}
    },
    onconfirm: (param) => {
      const {dialogInfo, remoteConfig, getFormAndcheckRequired} = param
      let remote;
      let newData = null;
      let needRefresh = unref(self.forceRefreshAfterUpdate);
      let form = getFormAndcheckRequired({form: dialogInfo.form, columns: dialogInfo.columns})
      if (!form) {
        return;
      }
      if ((dialogInfo.title || '').indexOf('编辑') >= 0) {
        newData = fixBlankFileds(dialogInfo.form, dialogInfo.form_ori, dialogInfo.columns)
        let newDataWithDiscard = fixBlankFileds(dialogInfo.form, dialogInfo.form_ori)
        if (!newData) {
          console.error('form', dialogInfo.form)
          console.error('form_ori', dialogInfo.form_ori)
          ElMessage.error(`未改动任何值`);
          return;
        }
        for(let item in dialogInfo.columns) {
          item = dialogInfo.columns[item]
          if (newDataWithDiscard[item.prop] !== null && newDataWithDiscard[item.prop] !== undefined) {
            if(item.refresh || item.discard) {
              needRefresh = true
            }
          }
        }
        remote = remoteConfig.edit
        if (!remote.keys || remote.keys.length == 0) {
          ElMessage.error(`未配置keys:${remote}`);
          return;
        }
        form = {...newData}
        if (form.query_options_setnull) {
          if (!('query_options' in form)) {
            form.query_options = {}
          }
          form.query_options.setnull = form.query_options_setnull
          delete form.query_options_setnull
        }
        for(let p in form) {
          let c = dialogInfo.columns.find(ele => ele.prop == p)
          if (c && form[p] === '' && c.empty_as_setnull) {
            if (!('query_options' in form)) {
              form.query_options = {}
            }
            if (!('setnull' in form.query_options)) {
              form.query_options.setnull = {}
            }
            form.query_options.setnull[p] = '';
            delete form[p]
          }
        }
        remote.keys.forEach(key => {
          form[key] = dialogInfo.form_ori[key]
        })
      } else {
        remote = remoteConfig.add
        needRefresh = true
        self.discardCount.value = false
      }
      dialogInfo.loading = true
      return post(remote.module, remote.method, form)
      .then( data => {
        if (data) {
          ElMessage.success(`修改成功`);
          return self.handleSearch({forceCount:true})
          .finally(() => {
            if (self.ShowAfterConfirm !== true) {
              dialogInfo.visible = false;
            }
            dialogInfo.loading = false
            if (self.custom.saveEditAfter) {
              self.custom.saveEditAfter({form, self})
            }
          })
        } else {
          ElMessage.error(`失败:${data}`);
          dialogInfo.loading = false
        }
      })
      .catch(err => {
        ElMessage.error(`失败:${err}`, err);
        dialogInfo.loading = false
      })
    },
    show: (param) => {
      const {dialogInfo, query, title} = param
      dialogInfo.title = title

      self.init_remote_list(self.editColumns.value, param)

      if (title == '编辑') {
        const selectRowData = getOnlySelectRowData(self.selectRows.value)
        if (!selectRowData) {
          return;
        }
        dialogInfo.form = {...selectRowData}
        dialogInfo.form_ori = self.selectRows.value[0]
        dialogInfo.columns.forEach( item => {
          if (item.type == 'upload') {
            try {
              let childNodes = document.getElementsByClassName('el-upload-list')[0].childNodes
              let childNodesCount = childNodes.length
              for(let childIndex = childNodesCount - 1; childIndex >= 0; childIndex--) {
                childNodes[childIndex].remove()
              }
            }catch(ex) {

            }

          }
          if (item.oninit) {
            let cb = item.oninit
            if (typeof(cb) == 'string') {
              cb = (dialogInfo.columns.find( item2 => item2.prop == cb) || {}).oninit
            }
            if(cb) {
              cb({...self, mode: 'init_dialog', form: dialogInfo.form, column: item, columns: dialogInfo.columns})
            }
          }
        })
        dialogInfo.columns.forEach( item => {
          if (item.onchange && dialogInfo.form[item.prop]) {
            let cb = item.onchange
            if (typeof(cb) == 'string') {
              cb = (dialogInfo.columns.find( item2 => item2.prop == cb) || {}).onchange
            }
            if(cb) {
              cb({...self, mode: 'init_dialog', form: dialogInfo.form, column: item, columns: dialogInfo.columns})
            }
          }
        })
      } else {
        dialogInfo.form = {}
        dialogInfo.form_ori = {}
        if (query.workspace_name) {
          let column = unref(self.editColumns).find(ele => ele.prop == 'workspace_name')
          if (column && column.hide !== true) {
            dialogInfo.form.workspace_name = query.workspace_name
          }
        }
        dialogInfo.columns.forEach( item => {
          if (item.oninit) {
            let cb = item.oninit
            if (typeof(cb) == 'string') {
              cb = (dialogInfo.columns.find( item2 => item2.prop == cb) || {}).oninit
            }
            if(cb) {
              cb({...self, mode: 'init_dialog', form: dialogInfo.form, column: item, columns: dialogInfo.columns})
            }
          }
        })
        dialogInfo.columns.forEach( item => {
          if (item.onchange && dialogInfo.form[item.prop]) {
            let cb = item.onchange
            if (typeof(cb) == 'string') {
              cb = (dialogInfo.columns.find( item2 => item2.prop == cb) || {}).onchange
            }
            if(cb) {
              cb({...self, mode: 'init_dialog', form: dialogInfo.form, column: item, columns: dialogInfo.columns})
            }
          }
        })
      }
      
      dialogInfo.visible = true
    },
    hide: (param) => {
      const {dialogInfo} = param
      dialogInfo.visible = false
      dialogInfo.loading = false
    },
  })

  self.columns.value.forEach( item => {
    if (item.required) {
      let obj = {}
      obj[item.prop] = { required: true, trigger: 'blur', message: '请输入'+item.label },
      self.form_rules.value.push(obj)
    }
  })

  self.queryColumns.value.forEach( item => {
    if (!item.label) {
      let col = unref(self.columns).find(ele => ele.prop == item.prop)
      if (col) {
        item.label = col.label
      }
    }
  })

  self.queryColumns.value.forEach( item => {
    if (item.oninit) {
      item.oninit({...self, mode: 'init', form: self.query.value, column: item, columns: self.queryColumns.value})
    }
  })

  self.queryColumns.value.forEach( item => {
    if (self.query.value[item.prop] && item.onchange) {
      item.onchange({...self, mode: 'init', form: self.query.value, column: item, columns: self.queryColumns.value})
    }
  })

  self.onChange = onChange

  self.onFocus = onFocus

  self.onMounted = (v) => {
    if (v) {
      for(let p in v) {
        self[p].value = v[p].value;
      }
    }
    self.sortMethod();
    if (self.refresh_oninit !== false) {
      self.handleSearch();
    }
    if (self.custom.onMounted) {
      self.custom.onMounted();
    }
  }

  if (self.custom && self.custom.onInit) {
    self.custom.onInit();
  }

}